﻿using log4net;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Web;

namespace Farkhod.BulkImageResizer.Helpers
{
    public class FileHelper
    {
        private ILog logger = LogManager.GetLogger(typeof(FileHelper).Name);

        public static FileHelper Instance
        {
            get
            {
                return Nested.FileHelper;
            }
        }

        private class Nested
        {
            static Nested() { }
            internal static readonly FileHelper FileHelper = new FileHelper();
        }

        #region commented
        //public string SaveResizedImage(string sourceFilePath, string sourceFileName, string resizedFilePath, string resizedFileName, int percent)
        //{
        //    string result = string.Empty;
        //    try
        //    {
        //        Image origImg = Image.FromFile(Path.Combine(sourceFilePath, sourceFileName));
        //        Image resizedImg = ScaleByPercent(origImg, percent);
        //        string sourceFileExtension = Path.GetExtension(sourceFileName).ToLower();
        //        string prefixToAdd = string.Empty;
        //        bool exceptionOccured = false;

        //        switch (sourceFileExtension)
        //        {
        //            case ".jpg":
        //            case ".jpeg":
        //                do
        //                {
        //                    try
        //                    {
        //                        resizedImg.Save(Path.Combine(resizedFilePath, prefixToAdd + resizedFileName), ImageFormat.Jpeg);
        //                        exceptionOccured = false;
        //                    }
        //                    catch (Exception ex)
        //                    {
        //                        if (ex.Message.Contains("A generic error occurred in GDI+"))
        //                        {
        //                            exceptionOccured = true;
        //                            prefixToAdd += "_";
        //                        }
        //                    }
        //                }
        //                while (exceptionOccured);
        //                break;

        //            case ".png":
        //                do
        //                {
        //                    try
        //                    {
        //                        resizedImg.Save(Path.Combine(resizedFilePath, prefixToAdd + resizedFileName), ImageFormat.Png);
        //                        exceptionOccured = false;
        //                    }
        //                    catch (Exception ex)
        //                    {
        //                        if (ex.Message.Contains("A generic error occurred in GDI+"))
        //                        {
        //                            exceptionOccured = true;
        //                            prefixToAdd += "_";
        //                        }
        //                    }
        //                }
        //                while (exceptionOccured);
        //                break;

        //            case ".bmp":
        //                do
        //                {
        //                    try
        //                    {
        //                        resizedImg.Save(Path.Combine(resizedFilePath, prefixToAdd + resizedFileName), ImageFormat.Bmp);
        //                        exceptionOccured = false;
        //                    }
        //                    catch (Exception ex)
        //                    {
        //                        if (ex.Message.Contains("A generic error occurred in GDI+"))
        //                        {
        //                            exceptionOccured = true;
        //                            prefixToAdd += "_";
        //                        }
        //                    }
        //                }
        //                while (exceptionOccured);
        //                break;

        //            default:
        //                //resizedImg.Save(Path.Combine(resizedFilePath, resizedFileName), ImageFormat.Jpeg);
        //                break;
        //        }
        //        resizedImg.Dispose();
        //        origImg.Dispose();

        //        result = Globals.RESIZE_AND_SAVE_IMAGE_SUCCESSFUL_RESULT;
        //    }
        //    catch (Exception ex)
        //    {
        //        logger.Error(ex.Message);
        //        result = ex.Message;
        //    }
        //    return result;
        //}
        #endregion

        public string SaveResizedImage(string sourceFilePath, string sourceFileName, string resizedFilePath, string resizedFileName, int percent)
        {
            string result = string.Empty;
            try
            {
                Image origImg = Image.FromFile(Path.Combine(sourceFilePath, sourceFileName));
                Image resizedImg = ScaleByPercent(origImg, percent);
                string sourceFileExtension = Path.GetExtension(sourceFileName).ToLower();
                switch (sourceFileExtension)
                {
                    case ".jpg":
                    case ".jpeg":
                        resizedImg.Save(Path.Combine(resizedFilePath, resizedFileName), ImageFormat.Jpeg);
                        break;

                    case ".png":
                        resizedImg.Save(Path.Combine(resizedFilePath, resizedFileName), ImageFormat.Png);
                        break;

                    case ".bmp":
                        resizedImg.Save(Path.Combine(resizedFilePath, resizedFileName), ImageFormat.Bmp);
                        break;

                    default:
                        break;
                }
                resizedImg.Dispose();
                origImg.Dispose();

                result = Globals.RESIZE_AND_SAVE_IMAGE_SUCCESSFUL_RESULT;
            }
            catch (Exception ex)
            {
                logger.Error(ex.Message);
                result = ex.Message;
            }
            return result;
        }

        public string SaveResizedImage(string sourceFilePath, string sourceFileName, string resizedFilePath, string resizedFileName, int height, int width)
        {
            string result = string.Empty;
            try
            {
                Image origImg = Image.FromFile(Path.Combine(sourceFilePath, sourceFileName));
                Image resizedImg = FixedSize(origImg, width, height);
                string sourceFileExtension = Path.GetExtension(sourceFileName).ToLower();
                switch (sourceFileExtension)
                {
                    case "jpg":
                    case "jpeg":
                        resizedImg.Save(Path.Combine(resizedFilePath, resizedFileName), ImageFormat.Jpeg);
                        break;

                    case "png":
                        resizedImg.Save(Path.Combine(resizedFilePath, resizedFileName), ImageFormat.Png);
                        break;

                    case "bmp":
                        resizedImg.Save(Path.Combine(resizedFilePath, resizedFileName), ImageFormat.Bmp);
                        break;

                    default:
                        resizedImg.Save(Path.Combine(resizedFilePath, resizedFileName), ImageFormat.Jpeg);
                        break;
                }
                resizedImg.Dispose();
                origImg.Dispose();

                result = Globals.RESIZE_AND_SAVE_IMAGE_SUCCESSFUL_RESULT;
            }
            catch (Exception ex)
            {
                logger.Error(ex.Message);
                result = ex.Message;
            }
            return result;
        }

        public Image ScaleByPercent(Image imgPhoto, int percent)
        {
            float nPercent = ((float)percent / 100);
            int sourceWidth = imgPhoto.Width;
            int sourceHeight = imgPhoto.Height;
            int sourceX = 0;
            int sourceY = 0;

            int destX = 0;
            int destY = 0;
            int destWidth = (int)(sourceWidth * nPercent);
            int destHeight = (int)(sourceHeight * nPercent);

            Bitmap bmPhoto = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);
            bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);

            Graphics grPhoto = Graphics.FromImage(bmPhoto);
            grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
            grPhoto.DrawImage(imgPhoto, new Rectangle(destX, destY, destWidth, destHeight), new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), GraphicsUnit.Pixel);

            grPhoto.Dispose();

            return bmPhoto;
        }

        public Image FixedSize(Image imgPhoto, int Width, int Height)
        {
            int sourceWidth = imgPhoto.Width;
            int sourceHeight = imgPhoto.Height;
            int sourceX = 0;
            int sourceY = 0;
            int destX = 0;
            int destY = 0;

            float nPercent = 0;
            float nPercentW = 0;
            float nPercentH = 0;

            nPercentW = ((float)Width / (float)sourceWidth);
            nPercentH = ((float)Height / (float)sourceHeight);
            if (nPercentH < nPercentW)
            {
                nPercent = nPercentH;
                destX = System.Convert.ToInt16((Width - (sourceWidth * nPercent)) / 2);
            }
            else
            {
                nPercent = nPercentW;
                destY = System.Convert.ToInt16((Height - (sourceHeight * nPercent)) / 2);
            }

            int destWidth = (int)(sourceWidth * nPercent);
            int destHeight = (int)(sourceHeight * nPercent);

            Bitmap bmPhoto = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
            bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);

            Graphics grPhoto = Graphics.FromImage(bmPhoto);
            grPhoto.Clear(Color.Red);
            grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
            grPhoto.DrawImage(imgPhoto, new Rectangle(destX, destY, destWidth, destHeight), new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), GraphicsUnit.Pixel);
            grPhoto.Dispose();

            return bmPhoto;
        }
    }
}